<?php

namespace app\admin\controller\scanwork;

use app\common\controller\Backend;
use think\Db;
use Exception;
use think\exception\PDOException;
use think\exception\ValidateException;

/**
 * 工资核算管理
 *
 * @icon fa fa-money
 * @remark 自动工资核算系统，基于生产数据自动计算工资
 */
class WageCalculation extends Backend
{
    /**
     * WageCalculation模型对象
     * @var \app\admin\model\scanwork\WageCalculation
     */
    protected $model = null;

    public function _initialize()
    {
        parent::_initialize();
        $this->model = new \app\admin\model\scanwork\WageCalculation;
        $this->view->assign("statusList", $this->model->getStatusList());
    }

    /**
     * 查看
     */
    public function index()
    {
        //设置过滤方法
        $this->request->filter(['strip_tags', 'trim']);
        if ($this->request->isAjax()) {
            //如果发送的来源是Selectpage，则转发到Selectpage
            if ($this->request->request('keyField')) {
                return $this->selectpage();
            }
            list($where, $sort, $order, $offset, $limit) = $this->buildparams();

            $list = $this->model
                ->with(['employee.user', 'confirmUser'])
                ->where($where)
                ->order($sort, $order)
                ->paginate($limit);

            $result = array("total" => $list->total(), "rows" => $list->items());

            return json($result);
        }
        return $this->view->fetch();
    }

    /**
     * 查看详情
     */
    public function detail($ids = null)
    {
        $row = $this->model->get($ids);
        if (!$row) {
            $this->error(__('No Results were found'));
        }
        
        // 获取核算明细
        $calculationDetails = $row->calculation_details;
        
        $this->view->assign('row', $row);
        $this->view->assign('calculationDetails', $calculationDetails);
        
        return $this->view->fetch();
    }

    /**
     * 创建工资核算
     */
    public function create()
    {
        // 获取员工列表
        $employeeList = \app\admin\model\scanwork\Employee::with(['user'])
            ->where('status', 1)
            ->select();
        $this->view->assign('employeeList', $employeeList);

        if ($this->request->isPost()) {
            $employeeId = $this->request->post('employee_id');
            $calculationDate = $this->request->post('calculation_date');
            $workType = $this->request->post('work_type', 'piece');
            
            if (!$employeeId || !$calculationDate) {
                $this->error('请选择员工和核算日期');
            }
            
            try {
                $calculation = $this->model->createCalculation($employeeId, $calculationDate, $workType);
                $this->success('工资核算创建成功', '', $calculation);
            } catch (Exception $e) {
                $this->error($e->getMessage());
            }
        }
        
        return $this->view->fetch();
    }

    /**
     * 批量创建工资核算
     */
    public function batchCreate()
    {
        if ($this->request->isPost()) {
            $employeeIds = $this->request->post('employee_ids', []);
            $calculationDate = $this->request->post('calculation_date');
            $workType = $this->request->post('work_type', 'piece');
            
            if (empty($employeeIds) || !$calculationDate) {
                $this->error('请选择员工和核算日期');
            }
            
            try {
                $result = $this->model->batchCreateCalculations($employeeIds, $calculationDate, $workType);
                
                $message = "批量创建完成！成功：{$result['success_count']}条，失败：{$result['error_count']}条";
                if (!empty($result['errors'])) {
                    $message .= "\n错误详情：\n" . implode("\n", $result['errors']);
                }
                
                $this->success($message);
            } catch (Exception $e) {
                $this->error($e->getMessage());
            }
        }
        
        // 获取员工列表
        $employeeList = \app\admin\model\scanwork\Employee::with(['user'])
            ->where('status', 1)
            ->select();
        $this->view->assign('employeeList', $employeeList);
        
        return $this->view->fetch();
    }

    /**
     * 确认工资核算
     */
    public function confirm($ids = null)
    {
        if (!$ids) {
            $this->error('参数错误');
        }
        
        $calculation = $this->model->get($ids);
        if (!$calculation) {
            $this->error('工资核算记录不存在');
        }
        
        try {
            $calculation->confirm($this->auth->id);
            $this->success('工资核算确认成功');
        } catch (Exception $e) {
            $this->error($e->getMessage());
        }
    }

    /**
     * 批量确认工资核算
     */
    public function batchConfirm()
    {
        $ids = $this->request->post('ids');
        if (!$ids) {
            $this->error('请选择要确认的记录');
        }
        
        $successCount = 0;
        $errorCount = 0;
        $errors = [];
        
        foreach ($ids as $id) {
            try {
                $calculation = $this->model->get($id);
                if ($calculation) {
                    $calculation->confirm($this->auth->id);
                    $successCount++;
                }
            } catch (Exception $e) {
                $errorCount++;
                $errors[] = "ID {$id}: " . $e->getMessage();
            }
        }
        
        $message = "批量确认完成！成功：{$successCount}条，失败：{$errorCount}条";
        if (!empty($errors)) {
            $message .= "\n错误详情：\n" . implode("\n", $errors);
        }
        
        $this->success($message);
    }

    /**
     * 发放工资
     */
    public function pay($ids = null)
    {
        if (!$ids) {
            $this->error('参数错误');
        }
        
        $calculation = $this->model->get($ids);
        if (!$calculation) {
            $this->error('工资核算记录不存在');
        }
        
        try {
            $calculation->pay();
            $this->success('工资发放成功');
        } catch (Exception $e) {
            $this->error($e->getMessage());
        }
    }

    /**
     * 批量发放工资
     */
    public function batchPay()
    {
        $ids = $this->request->post('ids');
        if (!$ids) {
            $this->error('请选择要发放的记录');
        }
        
        $successCount = 0;
        $errorCount = 0;
        $errors = [];
        
        foreach ($ids as $id) {
            try {
                $calculation = $this->model->get($id);
                if ($calculation) {
                    $calculation->pay();
                    $successCount++;
                }
            } catch (Exception $e) {
                $errorCount++;
                $errors[] = "ID {$id}: " . $e->getMessage();
            }
        }
        
        $message = "批量发放完成！成功：{$successCount}条，失败：{$errorCount}条";
        if (!empty($errors)) {
            $message .= "\n错误详情：\n" . implode("\n", $errors);
        }
        
        $this->success($message);
    }

    /**
     * 获取员工工资统计
     */
    public function getEmployeeStats()
    {
        $employeeId = $this->request->get('employee_id');
        $startDate = $this->request->get('start_date');
        $endDate = $this->request->get('end_date');
        
        if (!$employeeId) {
            $this->error('请选择员工');
        }
        
        $stats = $this->model->getEmployeeWageStats($employeeId, $startDate, $endDate);
        $this->success('', null, $stats);
    }

    /**
     * 获取工资核算汇总
     */
    public function getWageSummary()
    {
        $startDate = $this->request->get('start_date');
        $endDate = $this->request->get('end_date');
        
        $summary = $this->model->getWageSummary($startDate, $endDate);
        $this->success('', null, $summary);
    }

    /**
     * 工资统计报表
     */
    public function report()
    {
        $startDate = $this->request->get('start_date', date('Y-m-01'));
        $endDate = $this->request->get('end_date', date('Y-m-d'));
        
        // 获取汇总数据
        $summary = $this->model->getWageSummary($startDate, $endDate);
        
        // 获取员工工资统计
        $employeeStats = [];
        $employees = \app\admin\model\scanwork\Employee::with(['user'])->where('status', 1)->select();
        foreach ($employees as $employee) {
            $stats = $this->model->getEmployeeWageStats($employee->id, $startDate, $endDate);
            if ($stats['total_wage'] > 0) {
                $employeeStats[] = [
                    'employee_name' => $employee->employee_name,
                    'user_name' => $employee->user->nickname,
                    'position' => $employee->position,
                    'skill_level' => $employee->skill_level_text,
                    'total_wage' => $stats['total_wage'],
                    'total_piece_wage' => $stats['total_piece_wage'],
                    'total_time_wage' => $stats['total_time_wage'],
                    'total_overtime_wage' => $stats['total_overtime_wage'],
                    'total_quantity' => $stats['total_quantity'],
                    'total_hours' => $stats['total_hours'],
                    'calculation_count' => $stats['calculation_count']
                ];
            }
        }
        
        // 按总工资排序
        usort($employeeStats, function($a, $b) {
            return $b['total_wage'] <=> $a['total_wage'];
        });
        
        $this->view->assign('summary', $summary);
        $this->view->assign('employeeStats', $employeeStats);
        $this->view->assign('startDate', $startDate);
        $this->view->assign('endDate', $endDate);
        
        return $this->view->fetch();
    }

    /**
     * 导出工资报表
     */
    public function exportReport()
    {
        $startDate = $this->request->get('start_date', date('Y-m-01'));
        $endDate = $this->request->get('end_date', date('Y-m-d'));
        
        try {
            $spreadsheet = new \PhpOffice\PhpSpreadsheet\Spreadsheet();
            $sheet = $spreadsheet->getActiveSheet();
            
            // 设置标题
            $sheet->setCellValue('A1', '工资核算报表');
            $sheet->mergeCells('A1:K1');
            $sheet->setCellValue('A2', '统计期间：' . $startDate . ' 至 ' . $endDate);
            $sheet->mergeCells('A2:K2');
            
            // 设置表头
            $sheet->setCellValue('A4', '员工姓名');
            $sheet->setCellValue('B4', '用户名');
            $sheet->setCellValue('C4', '生产岗位');
            $sheet->setCellValue('D4', '技能等级');
            $sheet->setCellValue('E4', '计件工资');
            $sheet->setCellValue('F4', '计时工资');
            $sheet->setCellValue('G4', '加班工资');
            $sheet->setCellValue('H4', '总工资');
            $sheet->setCellValue('I4', '完成数量');
            $sheet->setCellValue('J4', '工作小时');
            $sheet->setCellValue('K4', '核算次数');
            
            // 获取员工工资统计
            $row = 5;
            $employees = \app\admin\model\scanwork\Employee::with(['user'])->where('status', 1)->select();
            foreach ($employees as $employee) {
                $stats = $this->model->getEmployeeWageStats($employee->id, $startDate, $endDate);
                if ($stats['total_wage'] > 0) {
                    $sheet->setCellValue('A' . $row, $employee->employee_name);
                    $sheet->setCellValue('B' . $row, $employee->user->nickname);
                    $sheet->setCellValue('C' . $row, $employee->position);
                    $sheet->setCellValue('D' . $row, $employee->skill_level_text);
                    $sheet->setCellValue('E' . $row, $stats['total_piece_wage']);
                    $sheet->setCellValue('F' . $row, $stats['total_time_wage']);
                    $sheet->setCellValue('G' . $row, $stats['total_overtime_wage']);
                    $sheet->setCellValue('H' . $row, $stats['total_wage']);
                    $sheet->setCellValue('I' . $row, $stats['total_quantity']);
                    $sheet->setCellValue('J' . $row, $stats['total_hours']);
                    $sheet->setCellValue('K' . $row, $stats['calculation_count']);
                    $row++;
                }
            }
            
            // 设置列宽
            $sheet->getColumnDimension('A')->setWidth(15);
            $sheet->getColumnDimension('B')->setWidth(15);
            $sheet->getColumnDimension('C')->setWidth(15);
            $sheet->getColumnDimension('D')->setWidth(15);
            $sheet->getColumnDimension('E')->setWidth(15);
            $sheet->getColumnDimension('F')->setWidth(15);
            $sheet->getColumnDimension('G')->setWidth(15);
            $sheet->getColumnDimension('H')->setWidth(15);
            $sheet->getColumnDimension('I')->setWidth(15);
            $sheet->getColumnDimension('J')->setWidth(15);
            $sheet->getColumnDimension('K')->setWidth(15);
            
            // 设置样式
            $sheet->getStyle('A1:K1')->getFont()->setBold(true)->setSize(14);
            $sheet->getStyle('A2:K2')->getFont()->setBold(true);
            $sheet->getStyle('A4:K4')->getFont()->setBold(true);
            $sheet->getStyle('A4:K4')->getAlignment()->setHorizontal(\PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER);
            
            // 设置边框
            $sheet->getStyle('A4:K' . ($row-1))->getBorders()->getAllBorders()->setBorderStyle(\PhpOffice\PhpSpreadsheet\Style\Border::BORDER_THIN);
            
            // 输出文件
            $writer = new \PhpOffice\PhpSpreadsheet\Writer\Xlsx($spreadsheet);
            $filename = '工资核算报表_' . $startDate . '_' . $endDate . '_' . date('YmdHis') . '.xlsx';
            
            header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
            header('Content-Disposition: attachment;filename="' . $filename . '"');
            header('Cache-Control: max-age=0');
            
            $writer->save('php://output');
            exit;
            
        } catch (Exception $e) {
            $this->error('导出失败：' . $e->getMessage());
        }
    }

    /**
     * 自动核算工资（定时任务）
     */
    public function autoCalculate()
    {
        $date = $this->request->get('date', date('Y-m-d', strtotime('-1 day')));
        
        try {
            $employees = \app\admin\model\scanwork\Employee::where('status', 1)->select();
            $successCount = 0;
            $errorCount = 0;
            $errors = [];
            
            foreach ($employees as $employee) {
                try {
                    // 检查是否已存在该日期的核算记录
                    $existing = $this->model->where([
                        'employee_id' => $employee->id,
                        'calculation_date' => $date
                    ])->find();
                    
                    if (!$existing) {
                        // 创建计件工资核算
                        $this->model->createCalculation($employee->id, $date, 'piece');
                        $successCount++;
                    }
                } catch (Exception $e) {
                    $errorCount++;
                    $errors[] = "员工【{$employee->employee_name}】: " . $e->getMessage();
                }
            }
            
            $message = "自动核算完成！成功：{$successCount}条，失败：{$errorCount}条";
            if (!empty($errors)) {
                $message .= "\n错误详情：\n" . implode("\n", $errors);
            }
            
            $this->success($message);
            
        } catch (Exception $e) {
            $this->error('自动核算失败：' . $e->getMessage());
        }
    }
}
